#include "StdAfx.h"
#include "Generic.h"

using namespace std;

void Generic::UseFilter()
{
	int intArray[] = {3, 4, 2, 1, 6, 5};

	vector<int> *mMyVector = new vector<int>(intArray, intArray+6);
	sort((*mMyVector).begin(), (*mMyVector).end());

	ostream_iterator<int> output(cout, " ");
	vector<int> temp;
	Filter((*mMyVector).begin(), (*mMyVector).end(), back_inserter(temp), 4, less<int>());

	cout << "Original array: ";
	copy(intArray, intArray+(sizeof(intArray) / sizeof(int)), output);
	cout << endl << "Filtered array (pivot = 4): ";
	copy(temp.begin(), temp.end(), output);
	cout << endl;
}

void Generic::UseAggregate()
{
	Aggregate(1, multiplies<int>());
}

template<typename InputIterator, typename OutputIterator, typename ElementType, typename CompFunc>
OutputIterator Generic::Filter(InputIterator first, 
							   InputIterator last, 
							   OutputIterator at, 
							   const ElementType &value,
							   CompFunc predicate)
{
	while((first = find_if(first, last, bind2nd(predicate, value))) != last)
	{
		*at++ = *first++;
	}

	return at;
}

template<typename ElementType, typename Func>
void Generic::Aggregate(const ElementType &value, Func function)
{
	cout << "Input numbers (q=quit): " << endl;

	vector<ElementType> v;

	istream_iterator<ElementType> input_end;
	istream_iterator<ElementType> input_start(cin);

	copy(input_start, input_end, back_inserter(v));

	int product = accumulate(v.begin(), v.end(), value, function);
	cout << "Result: " << product;
}
